/**
 * Copyright ®2015 sinosoft Co. Ltd. All rights reserved. 
 */
package com.gavinwind.inspay.common.util;

import com.gavinwind.inspay.common.dto.Response;
import com.gavinwind.inspay.common.dto.TransResult;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.mapper.DefaultMapper;
import com.thoughtworks.xstream.mapper.XStream11XmlFriendlyMapper;
import org.apache.commons.lang.StringUtils;

/**
 * xtream xml 序列化反序列化组件
 * 
 * @author fusq
 * @version 1.0
 * @created 30-七月-2010 16:21:53
 */
@SuppressWarnings("deprecation")
public class XStreamComponent {

    /**
     * 
     */
    private static final String DELIMITER = ".";

    /**
     * xstream xml转换引擎
     */
    private XStream xstream;

    /**
     * 创建XStreamComponent实例
     * 
     * @return XStreamComponent
     */
    public static XStreamComponent newInstance() {
        XStreamComponent tXmlComponent = new XStreamComponent();
        return tXmlComponent;
    }

    /**
     * XStreamComponent构造函数
     */
    public XStreamComponent() {
        this.xstream = new XStream(new DomDriver());
    }

    /**
     * 将对象序列化为xml string
     * 
     * @param cObj
     *      参数
     * @return String
     */
    public String toXML(Object cObj) {
        return this.xstream.toXML(cObj);
    }

    /**
     * 将分页对象序列化为xml string，官方api以不推荐使用
     * @param cObj
     *      参数
     * @return String
     */
    @Deprecated
    public String toPageXML(Object cObj) {
        this.registerConverter(new XStreamMapConverter(new DefaultMapper(XStream11XmlFriendlyMapper.class.getClassLoader())));
        return this.toXML(cObj);
    }

    /**
     * 将分页对象反序列化为Object，官方Api以不推荐使用
     * @param cXml
     *      参数
     * @return Object
     */
    @Deprecated
    public Object fromPageXML(String cXml) {
        this.registerConverter(new XStreamMapConverter(new DefaultMapper(XStream11XmlFriendlyMapper.class.getClassLoader())));
        return this.fromXML(cXml);
    }

    /**
     * 将xml string反序列化为object
     * 
     * @param cXml
     *      参数
     * @return Object
     */
    public Object fromXML(String cXml) {
        int tIndex = cXml.indexOf("?>");
        if (tIndex >= 0) {
            cXml = cXml.substring(tIndex + 2);
            return this.xstream.fromXML(cXml);
        } else {
            return this.xstream.fromXML(cXml);
        }

    }

    /**
     * 激活xstream注解引擎
     * 
     * @param cType
     *            Class
     */
    public void processAnnotations(Class<?> cType) {
        this.xstream.processAnnotations(cType);
    }

    /**
     * 激活xstream注解引擎
     * 
     * @param cTypes
     *            Class[]
     */
    @SuppressWarnings("rawtypes")
    public void processAnnotations(Class[] cTypes) {
        this.xstream.processAnnotations(cTypes);
        //xstream.aliasSystemAttribute(null, "class");
    }

    /**
     * 激活xstream注解引擎
     * 去除class属性
     * @param cTypes
     *            Class[]
     */
    @SuppressWarnings("rawtypes")
    public void processAnnotationsNoClass(Class[] cTypes) {
        this.xstream.processAnnotations(cTypes);
        xstream.aliasAttribute(null, "class");
    }

    /**
     * alias Class
     * 
     * @param cName
     *      参数
     * @param cType
     *      参数
     */
    public void alias(String cName, Class<?> cType) {
        this.xstream.alias(cName, cType);
    }

    /**
     * alias Class
     * 
     * @param cTypes
     *            Class[]
     */
    public void alias(Class<?>[] cTypes) {
        for (Class<?> tType : cTypes) {
            String tClassName = tType.getName();
            try {
                String[] tClassNames = StringUtils.split(tClassName, XStreamComponent.DELIMITER);
                this.xstream.alias(tClassNames[tClassNames.length - 1], tType);
            } catch (Exception ex) {
                this.xstream.alias(tClassName, tType);
            }
            //            xstream.aliasSystemAttribute(null, "class");
        }
    }

    /**
     * alias Response model of Webservice
     * 
     * @param cTypes
     *      参数
     */
    public void aliasResponse(Class<?>[] cTypes) {
        this.alias("Response", Response.class);
        this.alias("TransResult", TransResult.class);
        this.alias(cTypes);
    }

    /**
     * 注册xstream's converter
     * @param cConverter
     *      参数
     */
    public void registerConverter(Converter cConverter) {
        this.xstream.registerConverter(cConverter);
    }

    /**
     * 设置bean属性为xml的属性
     * @param cDefinedIn
     *      参数
     * @param cFieldName
     *      参数
     */
    public void useAttributeFor(Class<?> cDefinedIn, String cFieldName) {
        this.xstream.useAttributeFor(cDefinedIn, cFieldName);
    }

}
